package org.ns.longhttp.wrapper;


import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.cookie.Cookie;
import io.netty.handler.codec.http.cookie.ServerCookieDecoder;
import org.ns.longhttp.ResponseUtil;

import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UrlParameterMap {
    public final static Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
    private String url;
    private String queryString;
    private Map<String, String> parameters = new HashMap<>();
    private Map<String, Cookie> cookieMap = new HashMap<>();
    private Charset charset = DEFAULT_CHARSET;
    public UrlParameterMap(FullHttpRequest req) {
        this(req, DEFAULT_CHARSET);
    }
    public UrlParameterMap(FullHttpRequest req, Charset charset) {
        String uri = req.uri();
        if (charset == null) {
            charset = DEFAULT_CHARSET;
        }
        this.charset = charset;
        int index = uri.indexOf("?");
        if (index == -1) {
            url = uri;
        } else {
            url = uri.substring(0, index);
            queryString = uri.substring(index + 1);
            String[] split = queryString.split("&");
            for (String item : split) {
                int keyindex = item.indexOf("=");
                if (keyindex != -1) {
                    String key = item.substring(0, keyindex);
                    String val = item.substring(keyindex+1);
                    try {
                        parameters.put(key, URLDecoder.decode(val, charset.name()));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        HttpHeaders headers = req.headers();
        String cookieText = headers.get(HttpHeaderNames.COOKIE);
        List<Cookie> cookies = ResponseUtil.getCookie(cookieText);
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                cookieMap.putIfAbsent(cookie.name(), cookie);
            }
        }
    }

    public String getParameter(String name) {
        return this.parameters.get(name);
    }

    public Cookie getCookie(String name) {
        return this.cookieMap.get(name);
    }

    public Result getParameterOrCookieValue(String name) {
        String value = getParameter(name);
        // System.out.println(value);
        if (value == null || value.isEmpty()) {
            Cookie cookie = getCookie(name);
            if (cookie != null) {
                value = cookie.value();
            }
        }
        return new Result(value);
    }

    public Integer getInt(String name, Integer def) {
        String value = this.parameters.get(name);
        return toInt(value, def);
    }

    public Long getLong(String name, Long def) {
        String value = this.parameters.get(name);
        return toLong(value, def);
    }

    public static class Result {
        String value = null;

        public Result(String value) {
            this.value = value;
        }
        public Integer getInt(Integer def) {
            return toInt(value, def);
        }

        public Long getLong(Long def) {
            return toLong(value, def);
        }
    }



    protected static Integer toInt(String value, Integer def) {
        if (value == null || value.isEmpty()) {
            return def;
        }
        int index = value.indexOf(".");
        if (index != -1) {
            value = value.substring(0, index);
        }
        try {
            return Integer.parseInt(value.trim());
        } catch (Exception e) {
            return def;
        }
    }

    protected static Long toLong(String value, Long def) {
        if (value == null || value.isEmpty()) {
            return def;
        }
        int index = value.indexOf(".");
        if (index != -1) {
            value = value.substring(0, index);
        }
        try {
            return Long.parseLong(value.trim());
        } catch (Exception e) {
            return def;
        }
    }
}
